package com.h3c.nem.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.eos.common.util.DateUtils;
import com.eos.common.util.IdWorker;
import com.h3c.nem.client.PsaClient;
import com.h3c.nem.dto.PsaDataDTO;
import com.h3c.nem.dto.PsaTbTrainWorkerDTO;
import com.h3c.nem.dto.enums.TodoTaskNodeEnum;
import com.h3c.nem.entity.*;
import com.h3c.nem.mapper.SdTodoTaskMapper;
import com.h3c.nem.mapper.TbApprovalRecordMapper;
import com.h3c.nem.mapper.TbTrainClassMapper;
import com.h3c.nem.mapper.TbTrainWorkerMapper;
import com.h3c.nem.service.CommService;
import com.h3c.nem.service.ISdTodoTaskService;
import com.h3c.nem.service.ITbTrainWorkerService;
import com.h3c.nem.dto.TbTrainWorkerDTO;
import com.h3c.nem.utils.AppBusinessException;
import com.h3c.nem.utils.BusiEnumDefine;
import com.h3c.nem.utils.EncryptionUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Copyright (C), 2020-2020, h3c
 * FileName: TbTrainWorkerServiceImpl
 *
 * @Author: j26296
 * @Date: 2022-06-20
 * Description: tb_train_worker serviceImpl
 * Version: 1.0
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class TbTrainWorkerServiceImpl extends ServiceImpl<TbTrainWorkerMapper, TbTrainWorker> implements ITbTrainWorkerService {
    @Resource
    private PsaClient psaClient;

    @Resource
    private TbTrainWorkerMapper tbTrainWorkerMapper;
    @Resource
    private TbTrainClassMapper tbTrainClassMapper;
    @Resource
    private SdTodoTaskMapper sdTodoTaskMapper;
    @Resource
    private TbApprovalRecordMapper tbApprovalRecordMapper;
    @Autowired
    private ISdTodoTaskService todoTaskService;
    @Autowired
    private CommService commService;

    private static final String systemId = "HR_NEM";

    @Value("${oneMail.url}")
    String oneMailUrl;
    /**
     * @title: selectFuzzyByDto
     * @description: 模糊查询操作
     * @params: [ dto ]
     * @return: java.util.List
     * @createTime: 2022-06-20
     * @version: 1.0
     * @author: j26296
     */
    @Override
    public TbTrainWorkerDTO selectFuzzyByDto(TbTrainWorkerDTO dto) {
        String docid = dto.getDocid();
        String classId = "";
        try {
            TbApprovalRecord approvalRecord = tbApprovalRecordMapper.selectOne(new QueryWrapper<TbApprovalRecord>()
                    .eq("flow_id",docid)
                    .eq("approval_user_id",dto.getWorkerId()));
            classId = approvalRecord.getApprovalNote();
        }catch (Exception e){
            throw  new AppBusinessException("无法找到当前员工班级！");
        }
        TbTrainWorker tbTrainWorker = tbTrainWorkerMapper.selectOne(new QueryWrapper<TbTrainWorker>()
                .eq("class_id",classId)
                .eq("worker_id",dto.getWorkerId()));
        BeanUtils.copyProperties(tbTrainWorker,dto);

        return dto;
    }

    @Override
    public TbTrainWorkerDTO getLetterContent(TbTrainWorkerDTO dto){
        String checkTime = EncryptionUtil.getDecryptDataAES(dto.getCheckTime());
        Long time = null;
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            time= sdf.parse(checkTime).getTime();
//             time =DateUtils.dateParse(checkTime, "yyyy-MM-dd HH:mm:ss").getTime();
        }catch (Exception e){
            throw new AppBusinessException("时间解析错误！");
        }
        Long refenrenceTime =System.currentTimeMillis()-600000;
        if(refenrenceTime>time){
            throw new AppBusinessException("访问已过期！");
        }

        TbTrainWorker tbTrainWorker = tbTrainWorkerMapper.selectOne(new QueryWrapper<TbTrainWorker>()
                .eq("class_id",EncryptionUtil.getDecryptDataAES(dto.getClassId()))
                .eq("worker_id",EncryptionUtil.getDecryptDataAES(dto.getWorkerId())));
        BeanUtils.copyProperties(tbTrainWorker,dto);
        return dto;
    }

    /**
     * @title: selectByDto
     * @description: 精确查询操作
     * @params: [ dto ]
     * @return: java.util.List
     * @createTime: 2022-06-20
     * @version: 1.0
     * @author: j26296
     */
    @Override
    public List<TbTrainWorkerDTO> selectByDto(TbTrainWorkerDTO dto) {
        List<TbTrainWorker> list = tbTrainWorkerMapper.queryList(JSONObject.parseObject(JSONObject.toJSONString(dto),TbTrainWorker.class));
        return JSONArray.parseArray(JSONArray.toJSONString(list), TbTrainWorkerDTO.class);
    }

    /**
     * @title: insertDto
     * @description: 插入操作
     * @params: [ dto ]
     * @return: Integer
     * @createTime: 2022-06-20
     * @version: 1.0
     * @author: j26296
     */
    @Override
    public Integer insertDto(TbTrainWorkerDTO dto) {
        //if (null == dto.getId() || "".equals(dto.getId())) {
        //    String pkId = IdWorker.nextId() + "";
        //    dto.setId(pkId);
        //}
        return tbTrainWorkerMapper.insertTbTrainWorker(JSONObject.parseObject(JSON.toJSONString(dto), TbTrainWorker.class));
    }

    /**
     * @title: updateDto
     * @description: 修改操作
     * @params: [ dto ]
     * @return: Integer
     * @createTime: 2022-06-20
     * @version: 1.0
     * @author: j26296
     */
    @Override
    public Integer updateDto(TbTrainWorkerDTO dto) {
        String docid = dto.getDocid();
        String classId = "";
        try {
            TbApprovalRecord approvalRecord = tbApprovalRecordMapper.selectOne(new QueryWrapper<TbApprovalRecord>()
                    .eq("flow_id",docid)
                    .eq("approval_user_id",dto.getWorkerId()));
            classId = approvalRecord.getApprovalNote();
        }catch (Exception e){
            throw  new AppBusinessException("无法找到当前员工班级！");
        }
        TbTrainWorker tbTrainWorker = JSONObject.parseObject(JSON.toJSONString(dto),TbTrainWorker.class);
        return  tbTrainWorkerMapper.update(tbTrainWorker,new QueryWrapper<TbTrainWorker>()
                .eq("class_id",classId)
                .eq("worker_id",dto.getWorkerId()));
    }


    @Override
    public void submitOneMail(TbTrainWorkerDTO dto){
        dto.setLetterCommitTime(new Date());
        dto.setLetterStatus(BusiEnumDefine.ONE_MAIL_STATUS_COMMIT);
        updateDto(dto);
        //待办
        SdAllWorker sdAllWorker = commService.getAllWorkerDoFromLocalCache(dto.getWorkerId());
        SdTodoTask sdTodoTask = sdTodoTaskMapper.selectOne(new QueryWrapper<SdTodoTask>()
                .eq("docunid",dto.getDocid())
                .eq("adduserid",sdAllWorker.getDomainAccount()));
        sdTodoTask.setAuthorid("");
        sdTodoTask.setAuthorname("");
        sdTodoTask.setStatus("APPROVED");

        todoTaskService.update(sdTodoTask,new QueryWrapper<SdTodoTask>()
                .eq("docunid",dto.getDocid())
                .eq("adduserid",sdAllWorker.getDomainAccount()));
        todoTaskService.sendTodoTask(sdTodoTask);

        TbApprovalRecord approvalRecord = tbApprovalRecordMapper.selectOne(new QueryWrapper<TbApprovalRecord>()
                .eq("flow_id",dto.getDocid())
                .eq("approval_user_id",dto.getWorkerId()));

        TbTrainWorker tbTrainWorker = tbTrainWorkerMapper.selectOne(new QueryWrapper<TbTrainWorker>()
                .eq("class_id",approvalRecord.getApprovalNote())
                .eq("worker_id",dto.getWorkerId()));

        PsaTbTrainWorkerDTO psaTbTrainWorkerDTO = new PsaTbTrainWorkerDTO();
        BeanUtils.copyProperties(tbTrainWorker,psaTbTrainWorkerDTO);
        psaTbTrainWorkerDTO.setLetterStatusCN(BusiEnumDefine.ONE_MAIL_STATUS_COMMITCN);
        if(psaTbTrainWorkerDTO.getPushLetterFlag()==1){
            psaTbTrainWorkerDTO.setLetterIsPushNeed("是");
        }else {
            psaTbTrainWorkerDTO.setLetterIsPushNeed("否");
        }
        if(psaTbTrainWorkerDTO.getWriteLetterFlag()==1){
            psaTbTrainWorkerDTO.setLetterIsWriteNeed("是");
        }else{
            psaTbTrainWorkerDTO.setLetterIsWriteNeed("否");
        }
        psaTbTrainWorkerDTO.setLetterContent("");//psa保存不了信件
        JSONObject jsonObject = psaClient.modifyPsaOneMailStatus(psaTbTrainWorkerDTO);
        PsaDataDTO psaDataDTO  = JSON.parseObject(jsonObject.toJSONString(),PsaDataDTO.class);
        if(!psaDataDTO.getSuccess()){
            throw  new AppBusinessException("psa保存错误！请联系管理员！");
        }
    }
    /**
     * @title: deleteDto
     * @description: 删除操作
     * @params: [ dto ]
     * @return: Integer
     * @createTime: 2022-06-20
     * @version: 1.0
     * @author: j26296
     */
    @Override
    public Integer deleteDto(TbTrainWorkerDTO dto) {
        //if (null != dto && null != dto.getId() && !"".equals(dto.getId())) {
            return tbTrainWorkerMapper.deleteTbTrainWorker(JSONObject.parseObject(JSON.toJSONString(dto), TbTrainWorker.class));
            //return tbTrainWorkerMapper.deleteByPrimaryKey(dto.getId());
        //} else {
        //    return 0;
        //}
    }

    @Override
    public void  sendOneMail(List<TbTrainWorker> tbTrainWorkers,String classId){
        List<SdTodoTask> sdTodoTaskList = new ArrayList<>();
        for (TbTrainWorker tbTrainWorker : tbTrainWorkers) {
         senToDoTask(tbTrainWorker,classId);
        }
    }

    public void senToDoTask (TbTrainWorker tbTrainWorker,String classId){
        SdAllWorker sdAllWorker = commService.getAllWorkerDoFromLocalCache(tbTrainWorker.getWorkerId());
        SdTodoTask sdTodoTask = new SdTodoTask();
        sdTodoTask.setDocunid(IdWorker.nextId() + "");
        //todo 配置url
        sdTodoTask.setProcessid(BusiEnumDefine.oneMail);
        sdTodoTask.setProcessname("未来的一封信填写");
        sdTodoTask.setUrl(oneMailUrl+"?docid="+sdTodoTask.getDocunid());
        sdTodoTask.setRedirecturl(oneMailUrl+"?docid="+sdTodoTask.getDocunid());
        sdTodoTask.setNodeid(TodoTaskNodeEnum.ONE_MAIL.toString());
        sdTodoTask.setNodename(TodoTaskNodeEnum.ONE_MAIL.getName());
        sdTodoTask.setAccepttype(BusiEnumDefine.TODO_ACCEPT_PC_MOBILE);
        sdTodoTask.setAdduserid(sdAllWorker.getDomainAccount());
        sdTodoTask.setAddusername(tbTrainWorker.getWorkerName());
        sdTodoTask.setAuthorid(sdAllWorker.getDomainAccount());
        sdTodoTask.setAuthorname(tbTrainWorker.getWorkerName());
        sdTodoTask.setAppid("hr-nem");
        sdTodoTask.setSubject("未来的一封信填写");
        sdTodoTask.setSystemid(systemId);
        sdTodoTask.setIsbatch("0"); //能否批量处理（1是\0否）
        sdTodoTask.setEnduserid("");
        sdTodoTask.setStatus(BusiEnumDefine.PERFORMANCE_TODO_APPROVING);
        String timeStrNow = DateUtils.dateFormat(new Date(), "yyyy-MM-dd HH:mm:ss");
        sdTodoTask.setApplytime(timeStrNow);
        sdTodoTask.setTimestamp(timeStrNow);

        //approvalRecord:
        //flowId:待办docunid
        // approvalUserId：学员工号
        //approvalNote:班级Id
        TbApprovalRecord approvalRecord = new TbApprovalRecord();
        approvalRecord.setApprovalId(IdWorker.nextId()+"");
        approvalRecord.setApprovalUserId(tbTrainWorker.getWorkerId());
        approvalRecord.setFlowId(sdTodoTask.getDocunid());
        approvalRecord.setApprovalType(BusiEnumDefine.APPROVAL_TYPE_ONE_MAIL);
        approvalRecord.setApprovalNote(classId);
        approvalRecord.setFlowArriveTime(new Date());
        tbApprovalRecordMapper.insertTbApprovalRecord(approvalRecord);

        todoTaskService.save(sdTodoTask);
        todoTaskService.sendTodoTask(sdTodoTask);
    }

    /*
    * 提交一封信后，回退，允许重新填写
    * */
    @Override
    public void reback(PsaTbTrainWorkerDTO dto){

        QueryWrapper queryWrapper = new QueryWrapper<TbTrainWorker>()
                .eq("class_id",dto.getClassId())
                .eq("worker_id",dto.getWorkerId());
        TbTrainWorker tbTrainWorker = tbTrainWorkerMapper.selectOne(queryWrapper);
        if(Objects.isNull(tbTrainWorker)){
            throw new AppBusinessException("当前员工未启动一封信填写！");
        }
        //原状态为已提交或超时未提交，传过来的状态为填写中
        if((tbTrainWorker.getLetterStatus()==BusiEnumDefine.ONE_MAIL_STATUS_COMMIT||tbTrainWorker.getLetterStatus()==BusiEnumDefine.ONE_MAIL_STATUS_TIMEOVER)&&BusiEnumDefine.ONE_MAIL_STATUS_WRITINGCN.equals(dto.getLetterStatusCN())){
            tbTrainWorker.setLetterStatus(BusiEnumDefine.ONE_MAIL_STATUS_WRITING);
            //修改状态
            tbTrainWorkerMapper.update(tbTrainWorker,queryWrapper);
            SdAllWorker sdAllWorker = commService.getAllWorkerDoFromLocalCache(dto.getWorkerId());
            //重启代办
            TbApprovalRecord approvalRecord = tbApprovalRecordMapper.selectOne(new QueryWrapper<TbApprovalRecord>()
                    .eq("approval_note",dto.getClassId())
                    .eq("approval_user_id",dto.getWorkerId()));
            if(Objects.nonNull(approvalRecord)){
                String docid = approvalRecord.getFlowId();
                SdTodoTask sdTodoTask = sdTodoTaskMapper.selectOne(new QueryWrapper<SdTodoTask>()
                        .eq("docunid",docid));
                sdTodoTask.setAuthorid(sdAllWorker.getDomainAccount());
                sdTodoTask.setAuthorname(sdAllWorker.getWorkerName());
                sdTodoTask.setStatus("APPROVING");
                todoTaskService.updateTodoTask(sdTodoTask);
                todoTaskService.sendTodoTask(sdTodoTask);
            }else {
                senToDoTask(tbTrainWorker,dto.getClassId());
            }
        }

    }


    @Override
    public PsaTbTrainWorkerDTO searchLetterContent(PsaTbTrainWorkerDTO dto){
        QueryWrapper queryWrapper = new QueryWrapper<TbTrainWorker>()
                .eq("class_id",dto.getClassId())
                .eq("worker_id",dto.getWorkerId());
        TbTrainWorker tbTrainWorker = tbTrainWorkerMapper.selectOne(queryWrapper);
        if(Objects.isNull(tbTrainWorker)){
            return  new PsaTbTrainWorkerDTO();
        }
        PsaTbTrainWorkerDTO psaTbTrainWorkerDTO = new PsaTbTrainWorkerDTO();
        BeanUtils.copyProperties(tbTrainWorker,psaTbTrainWorkerDTO);

        if(psaTbTrainWorkerDTO.getPushLetterFlag()==1){
            psaTbTrainWorkerDTO.setLetterIsPushNeed("是");
        }else {
            psaTbTrainWorkerDTO.setLetterIsPushNeed("否");
        }
        if(psaTbTrainWorkerDTO.getWriteLetterFlag()==1){
            psaTbTrainWorkerDTO.setLetterIsWriteNeed("是");
        }else {
            psaTbTrainWorkerDTO.setLetterIsWriteNeed("否");
        }
        if(psaTbTrainWorkerDTO.getLetterStatus()==BusiEnumDefine.ONE_MAIL_STATUS_WAITING){
            psaTbTrainWorkerDTO.setLetterStatusCN(BusiEnumDefine.ONE_MAIL_STATUS_WAITINGCN);
        }else if(psaTbTrainWorkerDTO.getLetterStatus()==BusiEnumDefine.ONE_MAIL_STATUS_WRITING){
            psaTbTrainWorkerDTO.setLetterStatusCN(BusiEnumDefine.ONE_MAIL_STATUS_WRITINGCN);
        } else if(psaTbTrainWorkerDTO.getLetterStatus()==BusiEnumDefine.ONE_MAIL_STATUS_COMMIT){
            psaTbTrainWorkerDTO.setLetterStatusCN(BusiEnumDefine.ONE_MAIL_STATUS_COMMITCN);
        }else if(psaTbTrainWorkerDTO.getLetterStatus()==BusiEnumDefine.ONE_MAIL_STATUS_SEND){
            psaTbTrainWorkerDTO.setLetterStatusCN(BusiEnumDefine.ONE_MAIL_STATUS_SENDCN);
        }
        return psaTbTrainWorkerDTO;

    }

    //关闭超期待办
    @Override
    public void closeTimeOverTodoTask(){
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) - 7);
        Date before = calendar.getTime();  //倒退7天的时间
        List<TbTrainClass> tbTrainClassList = tbTrainClassMapper.selectList(new QueryWrapper<TbTrainClass>()
                .ge("begin_date",before)
        );
        List<String> classIdList = tbTrainClassList.stream().map(TbTrainClass::getClassId).collect(Collectors.toList());
        List<TbTrainWorker> tbTrainWorkerList = tbTrainWorkerMapper.selectList(new QueryWrapper<TbTrainWorker>()
                .in("class_id",classIdList)
                .in("letter_status",BusiEnumDefine.ONE_MAIL_STATUS_WRITING)
        );
        for (TbTrainWorker tbTrainWorker : tbTrainWorkerList) {
            TbApprovalRecord approvalRecord = tbApprovalRecordMapper.selectOne(new QueryWrapper<TbApprovalRecord>()
                    .eq("approval_note", tbTrainWorker.getClassId())
                    .eq("approval_user_id", tbTrainWorker.getWorkerId()));
            if (Objects.nonNull(approvalRecord)) {
                String docid = approvalRecord.getFlowId();
                SdTodoTask sdTodoTask = sdTodoTaskMapper.selectOne(new QueryWrapper<SdTodoTask>()
                        .eq("docunid", docid));
                sdTodoTask.setAuthorid("");
                sdTodoTask.setAuthorname("");
                sdTodoTask.setStatus("APPROVED");
                todoTaskService.updateTodoTask(sdTodoTask);
                todoTaskService.sendTodoTask(sdTodoTask);


                PsaTbTrainWorkerDTO psaTbTrainWorkerDTO = new PsaTbTrainWorkerDTO();
                BeanUtils.copyProperties(tbTrainWorker, psaTbTrainWorkerDTO);
                psaTbTrainWorkerDTO.setLetterStatusCN(BusiEnumDefine.ONE_MAIL_STATUS_TIMEOVERCN);
                if (psaTbTrainWorkerDTO.getPushLetterFlag() == 1) {
                    psaTbTrainWorkerDTO.setLetterIsPushNeed("是");
                } else {
                    psaTbTrainWorkerDTO.setLetterIsPushNeed("否");
                }
                if (psaTbTrainWorkerDTO.getWriteLetterFlag() == 1) {
                    psaTbTrainWorkerDTO.setLetterIsWriteNeed("是");
                } else {
                    psaTbTrainWorkerDTO.setLetterIsWriteNeed("否");
                }
                psaTbTrainWorkerDTO.setLetterContent("");//psa保存不了信件
                //修改psa状态
                JSONObject jsonObject = psaClient.modifyPsaOneMailStatus(psaTbTrainWorkerDTO);
                PsaDataDTO psaDataDTO = JSON.parseObject(jsonObject.toJSONString(), PsaDataDTO.class);
                if (!psaDataDTO.getSuccess()) {
                    throw new AppBusinessException("psa保存错误！请联系管理员！");
                }
            }
        }



    }


}
